package com.ivan.toolkit.common;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Verify;

import lombok.val;

public class Hex {
	
    final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' 
    };

	public static String toHex(byte b) {
		char[] c = new char[2];
		c[0] = digits[(b & 0xF0) >> 4];
		c[1] = digits[b & 0x0F];
		return new String(c);
	}
	
	public static String toHex(int b) {
		char[] c = new char[2];
		c[0] = digits[(b & 0xF0) >> 4];
		c[1] = digits[b & 0x0F];
		return new String(c);
	}
	
	public static char high(byte b) {
		return digits[(b & 0xF0) >> 4];
	}
	
	public static char high(int b) {
		return digits[(b & 0xF0) >> 4];
	}
	
	public static char low(byte b) {
		return digits[b & 0x0F];
	}
	
	public static char low(int b) {
		return digits[b & 0x0F];
	}
	
	public static String toHex(byte[] data, int offset, int length, int line_count) {
		
		StringBuilder sb = new StringBuilder();
		
		int count = 0;
		for(int i = 0; i < length; i++) {
			
			sb.append(high(data[i + offset]));
			sb.append(low(data[i + offset]));
			sb.append(' ');
			
			count++;
			
			if(count == line_count) {
				sb.append("\r\n");
				count = 0;
			}
		
		}
		
		return sb.toString();
		
	}
	
	public static String toHex(byte[] data, int line_count) {
		
		return toHex(data, 0, data.length, line_count);
		
	}
	

	public static byte[] hexStringToByteArray(String hex) throws Exception {
		
		// hex字符串不能为空
		Verify.verify(!Strings.isNullOrEmpty(hex), "校验字符串不能为空！ -> %s", hex);
    	
		// 判断输入字符串必须是偶数长度
		Verify.verify(0 == (hex.length() % 2), "校验字符串长度必须为偶数，请确认 -> %s", hex);
    	
    	// 分割字符串， 2个字符一�?
    	Splitter splitter = Splitter.fixedLength(2);       	
    	val vs = splitter.splitToList(hex);
    	Verify.verify(!vs.isEmpty(), "字符串分割时，没有得到任何结果！ -> %s", hex);

    	// 将字符数组挨个转化为byte，并放入byte数组
    	byte[] bytes = null;
		try {
			bytes = new byte[vs.size()];
			for(int i = 0; i < vs.size(); i++) {
				bytes[i] = (byte)(Integer.parseInt(vs.get(i), 16) & 0xFF);
			}
		} catch(Exception e) {
			Verify.verify(false, "16进制字符转换异常 -> %s", hex);
		}
		
		return bytes;
	}
	
}
